package cn.bonoon.kernel.descriptors;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import cn.bonoon.kernel.descriptors.impl.ConfigDescriptorImpl;
import cn.bonoon.kernel.descriptors.impl.EntityDescriptorImpl;
import cn.bonoon.kernel.descriptors.impl.ObjectDescriptorImpl;
import cn.bonoon.kernel.descriptors.impl.QueryDescriptorImpl;

public abstract class DescriptorFactory {
	
	private DescriptorFactory(){}

	/**
	 * 这里应该使用弱对象，当系统稳定下来ClassDescriptor不再需要被使用的时候，可以自动释放内存
	 */
	private final static Map<Class<?>, ObjectDescriptor> objectsCached = new ConcurrentHashMap<>();
	private final static Map<Class<?>, EntityDescriptor> entitiesCached = new ConcurrentHashMap<>();
	private final static Map<Class<?>, QueryDescriptor>  queriesCached = new ConcurrentHashMap<>();
	private final static Map<Class<?>, ConfigDescriptor> configsCached = new ConcurrentHashMap<>();
	
	public static final EntityDescriptor entityDescriptor(Class<?> entityClass) {
		EntityDescriptor ed = entitiesCached.get(entityClass);
		if (null == ed) {
			ed = new EntityDescriptorImpl(entityClass).initDescriptor();
			entitiesCached.put(entityClass, ed);
		}
		return ed;
	}

	public static final ObjectDescriptor objectDescriptor(Class<?> objectClass) {
		ObjectDescriptor cd = objectsCached.get(objectClass);
		if (null == cd) {
			cd = new ObjectDescriptorImpl(objectClass).initDescriptor();
			objectsCached.put(objectClass, cd);
		}
		return cd;
	}

	public static final QueryDescriptor queryDescriptor(Class<?> queryClass) {
		QueryDescriptor qd = queriesCached.get(queryClass);
		if (null == qd) {
			qd = new QueryDescriptorImpl(queryClass).initDescriptor();
			queriesCached.put(queryClass, qd);
		}
		return qd;
	}

	public static final ConfigDescriptor configDescriptorImpl(Class<?> configClass) {
		ConfigDescriptor ed = configsCached.get(configClass);
		if (null == ed) {
			ed = new ConfigDescriptorImpl(configClass).initDescriptor();
			configsCached.put(configClass, ed);
		}
		return ed;
	}
}
